本章节介绍了HTTPDNS C SDK的接入方法。
环境准备
SDK的集成依赖于必要的构建工具和第三方库,在集成SDK前请在构建机器上安装这些依赖。
名称 | 描述 | 版本 |
git | 版本控制工具 | 1.8及以上 |
cmake | 构建工具 | 3.0及以上 |
gcc | 编译工具 | 4.5及以上 |
vcpkg(可选) | 依赖库管理工具 | 推荐最新版本 |
libcurl | 应用层协议库 | 7.33.0及以上 |
apr/apr-util | C\C++跨平台组件库 | 1.5.2及以上 |
cjson | JSON字符串解析 | 推荐最新版本 |
构建工具安装
构建过程中需要使用git克隆代码、使用cmake构建工程、使用gcc/g++编译代码,请您确认这些命令行工具已经安装在本机,如果尚未安装,请参考以下命令安装:
Ubuntu/Debian
sudo apt update sudo apt install -y git cmake gcc g++
Aliyun/CentOS Stream/Fedora
sudo yum check-update sudo yum install -y git cmake gcc gcc-c++
OpenSUSE
sudo zypper refresh sudo zypper install -y git cmake gcc gcc-c++
macOS
export HOMEBREW_NO_AUTO_UPDATE=1 brew install git gcc cmake
说明注意:brew非macOS自带的包管理器,安装包之前请先安装brew。
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Windows
下载安装Git、下载安装Visual Studio (工作负载选择“使用C++的桌面开发”)
依赖库安装
SDK使用libcurl库(版本7.33.0及以上)进行网络操作,使用apr/apr-util(版本1.5.2及以上)库解决内存管理以及跨平台问题,使用cjson库解析服务端响应报文,SDK并没有带上这几个外部库,您需要确认这些库已经安装,并且将它们的头文件目录和库文件目录都加入到了项目中。本项目支持VCPKG安装和手动安装两种方式安装这些C/C++库。
VCPKG安装
安装SDK依赖的库
macOS/Linux
./vcpkg install apr apr-util curl[openssl,http2] cjson
Windows
.\vcpkg.exe install apr apr-util curl[openssl,http2] cjson
说明VCPKG 默认安装与当前平台相对应的库。如果需要进行跨平台编译,例如在 Windows x64 环境下编译 x86 库,则需指定 triplet。示例命令如下:
./vcpkg.exe install apr:x86-windows apr-util:x86-windows curl[openssl,http2]:x86-windows cjson:x86-windows
手动安装
Ubuntu/Debian
sudo apt update sudo apt install -y libcurl4-openssl-dev libapr1-dev libaprutil1-dev libcjson-dev
Aliyun/CentOS Stream/Fedora
sudo yum check-update sudo yum install -y libcurl-devel apr-devel apr-util-devel cjson-devel
OpenSUSE
sudo zypper refresh sudo zypper install -y libcurl-devel libapr1-devel libapr-util1-devel cJSON-devel
macOS
brew install curl apr apr-util cjson
Windows
注意:如果cJSON开发包不能通过Unix-like平台包管理器自动安装,可以通过以下命令手动安装:
git clone https://github.com/DaveGamble/cJSON.git && cd cJSON && mkdir build && cd build && cmake ../ && sudo make install && cd ../../ && rm -rf cJSON
SDK安装
Linux/macOS
git clone https://github.com/aliyun/alibabacloud-httpdns-c-sdk.git cd alibabacloud-httpdns-c-sdk mkdir build cd build # 如果是通过VCPKG安装的依赖库,则构建SDK时需要添加Cmake参数 -DVCPKG_ROOT=${vcpkg的安装路径} cmake -DCMAKE_BUILD_TYPE=Release ../ make hdns_unite_test sudo make install sudo ldconfig
Windows
下载工程
Visual Studio打开Cmake工程
管理配置中配置Cmake命令参数:-DVCPKG_ROOT=${vcpkg的安装路径}
SDK集成
SDK的集成可以参考C 集成示例,下面介绍具体集成步骤。
引入SDK
集成SDK需要引入安装在本地的库和头文件,以cmake工程为例,在工程CMakeLists.txt文件中加入以下命令:
find_library(HTTPDNS_LIBRARY httpdns_c_sdk_static)
include_directories(${CMAKE_INSTALL_PREFIX}/include/httpdns)
SDK初始化
SDK运行环境初始化。
if (hdns_sdk_init() != HDNS_OK) {
hdns_sdk_cleanup();
}
// 使用SDK API
客户端创建
hdns_client_t *client = hdns_client_create(HTTPDNS_ACCOUNT, HTTPDNS_SECRET);
if (client == NULL) {
hdns_sdk_cleanup();
}
// 使用HTTPDNS Client
客户端配置
客户端实例创建成功之后,如果用户希望对HTTPDNS 客户端进行自定义配置可以通过以下方式进行:
// 设置请求服务端超时时间,单位:ms
hdns_client_set_timeout(client, 2000);
// 是否开启本地缓存
hdns_client_set_using_cache(client, true);
// 是否使用https协议访问HTTPDNS服务端
hdns_client_set_using_https(client, true);
// 请求是否进行加签
hdns_client_set_using_sign(client, true);
// 请求服务端重试次数
hdns_client_set_retry_times(client, 1);
// 设置HTTPDNS解析服务集群
hdns_client_set_region(client, "global");
// 设置HTTPDNS调度集群
hdns_client_set_schedule_center_region(client, "cn");
// 设置网络变化后是否更新本地缓存
hdns_client_enable_update_cache_after_net_change(client, true);
// 是否允许获取过期缓存
hdns_client_enable_expired_ip(client, true);
// 是否自动降级到localdns
hdns_client_enable_failover_localdns(client, true);
// 添加预解析域名
hdns_client_add_pre_resolve_host(client, "www.aliyun.com");
// 添加Ip嗅探
hdns_client_add_ip_probe_item(client, "www.aliyun.com", 443);
// 自定义ttl
hdns_client_add_custom_ttl_item(client, "www.aliyun.com", 120);
客户端启动
hdns_client_start(client);
域名解析
客户端实例启动之后,就可以调用SDK提供的API进行域名解析了,SDK针对不同的场景提供了多个API接口,这里以单域名同步接口为例,展示调用API获取HTTPDNS解析结果的使用过程。
hdns_list_head_t *results = NULL;
hdns_status_t status = hdns_get_result_for_host_sync_with_cache(client,
MOCK_BUSINESS_HOST,
HDNS_QUERY_AUTO,
NULL, &results);
IP选择
通过SDK API获取域名的解析结果之后,就可以通过解析的IP访问客户的业务了。
if (hdns_status_is_ok(&status)) {
char ip[HDNS_IP_ADDRESS_STRING_LENGTH];
if (hdns_select_ip_randomly(results, HDNS_QUERY_AUTO, ip) == HDNS_OK) {
mock_access_business_web_server(ip);
}
}
if (hdns_status_is_ok(&status)) {
char ip[HDNS_IP_ADDRESS_STRING_LENGTH];
if (hdns_select_ip_randomly(results, HDNS_QUERY_AUTO, ip) == HDNS_OK) {
mock_access_business_web_server(ip);
}
}
hdns_list_free(results);
业务访问
static void mock_access_business_web_server(const char *dst_ip) {
CURL *curl;
CURLcode res;
curl = curl_easy_init();
if (curl) {
// 拼接业务URL
char url[256];
strcpy(url, "https://");
strcat(url, MOCK_BUSINESS_HOST);
curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30);
// HTTPS设置预解析的主机和 IP
struct curl_slist *dns;
char sni[256];
strcpy(sni, MOCK_BUSINESS_HOST);
strcat(sni, ":443:");
strcat(sni, dst_ip);
dns = curl_slist_append(NULL, sni);
curl_easy_setopt(curl, CURLOPT_RESOLVE, dns);
// 设置响应结果回调
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data_callback);
#if defined(_WIN32)
curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA);
#endif
// 发起HTTP请求
res = curl_easy_perform(curl);
if (res != CURLE_OK) {
fprintf(stderr, "curl_easy_perform() failed, url=%s, ip=%s, error=%s\n",
url,
dst_ip,
curl_easy_strerror(res));
}
// 释放业务访问相关资源
curl_slist_free_all(dns);
/* always cleanup */
curl_easy_cleanup(curl);
}
}
客户端清理
client不再使用后,需要将其释放。
hdns_client_cleanup(client);
SDK清理
SDK不再使用后,需要将其释放。
hdns_sdk_cleanup();